﻿///
/// Pamela.Logic.Imps
///
namespace Pamela.Logic.Imps.Mvc
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;

    using Pamela.Logic.Helpers;
    using Pamela.Logic.Imps.Base;    
    using Pamela.Logic.Properties;

    /// <summary>
    /// ServiceBuilder class
    /// </summary>
    internal class MvcServiceBuilder : BaseBuilder
    {
        /// <summary>
        /// Initializes a new instance of the ServiceBuilder class
        /// </summary>
        /// <param name="assembly">The shared DLL assembly</param>
        /// <param name="info">Builder  object containing all the info to necessary perform the scaffolding operation</param>
        public MvcServiceBuilder(Assembly assembly, BuilderInfo info, string layerName)
            : base(assembly, info, layerName, "service.template")
        {
        }

        /// <summary>
        /// Builds the service layer file based on the BuilderInfo provided
        /// </summary>
        public override void Build()
        {
            using (StreamReader template = new StreamReader(this.templatePath))
            using (StreamWriter output = new StreamWriter(this.builderInfo.ServiceDestinationFile))
            {
                while (template.Peek() >= 0)
                {
                    string buffer = template.ReadLine();

                    buffer = buffer.Replace(Resources.NamespaceBal, this.builderInfo.BusinessLayerNamespace);
                    buffer = buffer.Replace(Resources.NamespaceDal, this.builderInfo.DataLayerNamespace);
                    buffer = buffer.Replace(Resources.Namespace, this.builderInfo.RootNamespace);
                    buffer = buffer.Replace(Resources.SelectedModel, this.builderInfo.SelectedModel);
                    buffer = buffer.Replace(Resources.Entity, pluralizationService.Pluralize(this.builderInfo.SelectedModel));
                    buffer = buffer.Replace(Resources.Context, this.builderInfo.DatabaseContext);
                    buffer = buffer.Replace(Resources.Validation, this.GenerateValidationCode());

                    output.WriteLine(buffer);
                }
            }
        }

        /// <summary>
        /// Builds the validation code
        /// </summary>
        /// <returns>String representing the validation code</returns>
        private string GenerateValidationCode()
        {
            var typeName = string.Format("{0}.Models.{1}", this.builderInfo.SharedLayerNamespace, builderInfo.SelectedModel);
            var type = this.assembly.GetType(typeName);

            var result = new StringBuilder();

            foreach (var prop in type.GetProperties())
            {
                if (prop.GetMethod.IsVirtual)
                {
                    // skip to the next property
                    continue;
                }

                if (prop.PropertyType.Name == "String")
                {
                    result.Append("\t\t\t");
                    result.Append("if (string.IsNullOrEmpty(model." + prop.Name + "))");
                    result.Append("\r\n");
                    result.Append("\t\t\t\t");
                    result.Append(@"rules.Add(""" + prop.Name + @""", """ + prop.Name + @" field is required"");");
                    result.Append("\r\n");
                }

                if (prop.PropertyType.Name == "Int32")
                {
                    result.Append("\t\t\t");
                    result.Append("if (model." + prop.Name + " == 0)");
                    result.Append("\r\n");
                    result.Append("\t\t\t\t");
                    result.Append(@"rules.Add(""" + prop.Name + @""", """ + prop.Name + @" field is required"");");
                    result.Append("\r\n");
                }
            }

            return result.ToString();
        }
    }
}
